
#[macro_use]
extern crate log;

// #[no_mangle]
// pub static ONCE: std::sync::Once = std::sync::Once::new();

/// TestStruct 结构体
pub struct TestStruct {
    pub a: i32,
    pub b: i32,
}

pub struct TestStructLife<'a> {
    pub a: &'a i32,
    pub b: i32,
}

pub trait MyWrapperApi {
    fn test_print(&self, msg: String);
}


#[no_mangle]
pub static mut A_i32: i32 = 1;

#[no_mangle]
pub static B_STR: &str = "hello world";

#[no_mangle]
pub static C_I64: i64 = 3;

const BUILD_VERSION: &str = "---\t 2 \t---";

#[no_mangle]
pub fn test_print(msg: String) {
    if unsafe { A_i32 % 10_0000 == 0 } {
        log::debug!("test_print{BUILD_VERSION}: {msg} ");
    }
    std::thread::sleep(std::time::Duration::from_millis(500));
}

#[no_mangle]
pub fn test_return_result(msg: &str) -> String { 
    let mut i = 50_0000;
    let mut rmsg = "".to_string();
    while i > 0 {
        i -= 1;
        rmsg.push_str(&format!("{msg}: {i}"));
    }
    rmsg
}

#[no_mangle]
pub fn async_run(msg: &str) -> String { 
    let rt = tokio::runtime::Handle::current();
    let msg = rt.block_on(async {
        let mut i = 3000;
        let mut rmsg = "".to_string();
        while i > 0 {
            i -= 1;
            tokio::time::sleep(std::time::Duration::from_millis(1)).await;
            rmsg.push_str(&format!("{msg}: {i}"));
        }
        rmsg
    });

    msg
}

// #[no_mangle]
pub static STOP: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false);

#[no_mangle]
pub fn init_data(msg: String) {
    // 初始化日志
    std::env::set_var("RUST_LOG", "debug");
    env_logger::init();
    info!("call_lib env_logger starting up");

    warn!("init_data{BUILD_VERSION}: {msg} ");

    std::thread::spawn(move || loop {
        if STOP.load(std::sync::atomic::Ordering::Relaxed) {
            break;
        }
        debug!("thread{BUILD_VERSION}: {msg} ");
        std::thread::sleep(std::time::Duration::from_millis(999));
    });
}

#[no_mangle]
pub fn stop_runtime() {
    log::debug!("stop_thread{BUILD_VERSION}");
    STOP.store(true, std::sync::atomic::Ordering::SeqCst);
}

pub type AsyncType<T> = std::pin::Pin<Box<dyn std::future::Future<Output = T>>>;

#[no_mangle]
pub fn async_fn() -> AsyncType<()> {
    Box::pin(async {
        // Asynchronous business code can be written here; 此处可写异步业务代码
        if unsafe { A_i32 % 1000_0000 == 0 } {
            debug!("async_fn{BUILD_VERSION}");
        }
    })
}
